package znet

import (
	"bytes"
	"encoding/binary"
	"errors"
	"github.com/zinx/utils"
	"github.com/zinx/ziface"
)

type DataPack struct {
}

// 获取包的头的长度的方法
func (d *DataPack) GetHeadLen() uint32 {
	// datalen uint32 4 byte + id uint32 4 byte 共 8 byte
	return 8
}

// 封包方法
func (d *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
	// 创建字节的缓冲
	buffer := bytes.NewBuffer([]byte{})
	// 将datalen写进databuf中
	if err := binary.Write(buffer, binary.LittleEndian, msg.GetMsgLen()); err != nil {
		return nil, err
	}
	// 将msgid写进buf中
	if err := binary.Write(buffer, binary.LittleEndian, msg.GetMsgId()); err != nil {
		return nil, err
	}
	// 将data数据写入buf中
	if err := binary.Write(buffer, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

// 拆包方法
func (d *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error) {
	msg := &Message{}
	// 创建一个从输入二进制输入的ioReader
	reader := bytes.NewReader(binaryData)

	// 读取datalen
	if err := binary.Read(reader, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}
	// 读取msgId
	if err := binary.Read(reader, binary.LittleEndian, &msg.Id); err != nil {
		return nil, err
	}
	// 判断datalen是否已经超出了允许的最大长度
	if utils.GlobalObject.MaxPackageSize > 0 && msg.DataLen > utils.GlobalObject.MaxPackageSize {
		return nil, errors.New("too large msg data recv!")
	}

	return msg, nil
}

func NewDataPack() *DataPack {
	return &DataPack{}
}
